package com.yezao.processor

import com.yezao.processor.ktFile.KtClassBody
import com.yezao.processor.ktFile.KtClassMethod
import com.yezao.processor.ktFile.KtFileHeader
import com.yezao.processor.ktFile.KtFileObject
import com.yezao.processor.ktFile.apis.KtHeader
import com.yezao.yzannotation.KtRouter
import com.yezao.yzannotation.YZRouter
import java.io.File
import java.io.IOException
import java.lang.StringBuilder
import java.util.*
import javax.annotation.processing.*
import javax.lang.model.SourceVersion
import javax.lang.model.element.*
import javax.lang.model.util.Elements
import javax.lang.model.util.Types
import javax.tools.Diagnostic
import javax.tools.StandardLocation
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.jvm.Throws

@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedAnnotationTypes("com.yezao.yzannotation.KtRouter")
@SupportedOptions("moduleName","jsonPath","jsonFileName")
class KtProcessor: AbstractProcessor() {
    private var mLocale: Locale? = null
    private var mMessager: Messager? = null
    private var mTypeUtils: Types? = null
    private var mElements: Elements? = null
    private var mFilter: Filer? = null


    private var mJsonFilePath:String?=null
    private var mJsonFileName:String="yz-route-map.json"


    @Synchronized
    override fun init(processingEnv: ProcessingEnvironment) {
        super.init(processingEnv)
        println("=================init====================")

        mTypeUtils = processingEnv.typeUtils
        mElements = processingEnv.elementUtils
        mFilter = processingEnv.filer
        mMessager = processingEnv.messager

        mLocale = processingEnv.locale

        val options = processingEnv.options
        for (key in options.keys) {
            println("key " + key + ":" + options[key])
            if (key == "jsonPath"&&options[key]!=null) {
                mJsonFilePath = options[key]!!
            }
            if (key == "jsonFileName"&&options[key]!=null) {
                mJsonFileName = options[key]!!
            }
        }
    }


    private val mAnnotatedClass = HashMap<String,String>()

    override fun process(annotations: Set<TypeElement?>?, roundEnv: RoundEnvironment): Boolean {
        println("================process=================")
        val elementsAnnotated = roundEnv.getElementsAnnotatedWith(KtRouter::class.java)
        //收集被注解的类
        for (element in elementsAnnotated) {
            println("-----${element.simpleName}")
            val packageElement = mElements?.getPackageOf(element)
            println(packageElement)
            //保存类  和包名
            val annotation = element.getAnnotationsByType(KtRouter::class.java)

            mAnnotatedClass.put(element.toString(),annotation[0].router)
        }
        try {
            buildRouteMapJson()
        } catch (e: Exception) {

        }

        return true
    }

    private fun buildRouteMapJson(){
        val file = File(mJsonFilePath, mJsonFileName)
        if (file.exists()) {
            file.deleteRecursively()
        }
        file.parentFile.mkdirs()
        file.createNewFile()

        val stringBuilder = StringBuilder()
        stringBuilder.append("[")

        for ((fullClazsName,route) in mAnnotatedClass) {
            stringBuilder.append("\n")
            stringBuilder.append("    {\"route\":\"${route}\",")
            stringBuilder.append("\"value\":\"${fullClazsName}\"},")
            println("write json item  ${stringBuilder}")
        }
        stringBuilder.setLength(stringBuilder.length-1)
        stringBuilder.append("\n]")

        file.writeText(stringBuilder.toString())
    }

    private fun buildJavaClassFile(){

    }


    private fun buildKtClassFile(map:HashMap<Element,String>){
        val ktFileObject = KtFileObject()
        val packageName = "com.yezao.yzrouter"
        val clazsName = "YZRouterHelp.kt"

        val header = KtFileHeader(packageName, arrayListOf())
        ktFileObject.setHeader(header)
        val body = KtClassBody(clazsName)
        val ktClassMethod = KtClassMethod("public", "print", null, ArrayList())
        ktClassMethod.writeMethodContent(
            "println(\"this is process method\")"
        )
        body.addMethod(ktClassMethod)
        ktFileObject.setBody(body)

        mFilter?.createResource(StandardLocation.SOURCE_OUTPUT,packageName,clazsName)?.run {
            println(ktFileObject.toKtFile())
            openWriter().write(ktFileObject.toKtFile())
            openWriter().flush()
            openWriter().close()
        }
    }

}